<template>
  <div class="message"
       :class="cls">
    <div class="bubble">
      <!-- 文本/工具结果内容 -->
      <p v-if="isText"
         class="text">{{ message.content }}</p>
      <pre v-else-if="isToolResult"
           class="tool-result">{{ message.content }}</pre>
      <p v-else
         class="text">{{ message.content }}</p>

      <!-- 状态与操作栏 -->
      <div class="meta">
        <span class="time">{{ timeLabel }}</span>
        <span v-if="message.status === STATUS.SENDING"
              class="status sending">发送中...</span>
        <span v-else-if="message.status === STATUS.FAILED"
              class="status failed">发送失败</span>
        <button class="meta-btn"
                @click="onCopy">复制</button>
        <button v-if="message.sender === SENDER.USER && message.status === STATUS.FAILED"
                class="meta-btn retry"
                @click="emitRetry">重试</button>
      </div>
    </div>
  </div>
</template>

<script setup>
import { computed } from 'vue';
import { SENDER, MESSAGE_TYPE, MESSAGE_STATUS as STATUS } from '../../utils/constants';

/**
 * 单条消息组件
 * @prop {Object} message - 消息对象，包含 sender、content、status、type、timestamp
 * @emits retry(messageId) - 触发重试指定消息
 */
const props = defineProps({
  message: { type: Object, required: true }
});
const emit = defineEmits(['retry']);

// 根据发送者确定布局方向（左：助手，右：用户）
const cls = computed(() => {
  return props.message.sender === SENDER.USER ? 'right' : 'left';
});

// 类型判断
const isText = computed(() => props.message.type === MESSAGE_TYPE.TEXT);
const isToolResult = computed(() => props.message.type === MESSAGE_TYPE.TOOL_RESULT);

// 时间戳显示
const timeLabel = computed(() => {
  const ts = props.message.timestamp;
  if (!ts) return '';
  const d = new Date(ts);
  const yyyy = d.getFullYear();
  const mm = String(d.getMonth() + 1).padStart(2, '0');
  const dd = String(d.getDate()).padStart(2, '0');
  const hh = String(d.getHours()).padStart(2, '0');
  const mi = String(d.getMinutes()).padStart(2, '0');
  return `${yyyy}-${mm}-${dd} ${hh}:${mi}`;
});

// 复制功能
async function onCopy() {
  try {
    await navigator.clipboard.writeText(props.message.content || '');
  } catch (_) { /* noop */ }
}

// 重试事件
function emitRetry() {
  emit('retry', props.message.id);
}
</script>

<style scoped>
.message {
  display: flex;
  margin-bottom: 20px;
  animation: fadeInUp 0.4s cubic-bezier(0.4, 0, 0.2, 1);
}

@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.message.left {
  justify-content: flex-start;
}

.message.right {
  justify-content: flex-end;
}

.bubble {
  max-width: 75%;
  padding: 16px 20px;
  border-radius: 20px;
  background: rgba(255, 255, 255, 0.95);
  backdrop-filter: blur(10px);
  box-shadow: 0 4px 20px rgba(59, 130, 246, 0.08);
  border: 1px solid rgba(59, 130, 246, 0.1);
  position: relative;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

.bubble:hover {
  box-shadow: 0 8px 30px rgba(59, 130, 246, 0.15);
  transform: translateY(-2px);
}

.message.right .bubble {
  background: linear-gradient(135deg, #3b82f6 0%, #60a5fa 100%);
  color: white;
  border-color: rgba(255, 255, 255, 0.2);
}

.message.right .bubble:hover {
  box-shadow: 0 8px 30px rgba(59, 130, 246, 0.25);
}

/* 消息气泡尾巴 */
.bubble::before {
  content: '';
  position: absolute;
  width: 0;
  height: 0;
  border-style: solid;
}

.message.left .bubble::before {
  left: -8px;
  top: 20px;
  border-width: 8px 8px 8px 0;
  border-color: transparent rgba(255, 255, 255, 0.95) transparent transparent;
}

.message.right .bubble::before {
  right: -8px;
  top: 20px;
  border-width: 8px 0 8px 8px;
  border-color: transparent transparent transparent #3b82f6;
}

.text {
  white-space: pre-wrap;
  word-break: break-word;
  line-height: 1.6;
  font-size: 15px;
  margin: 0;
  color: #374151;
}

.message.right .text {
  color: white;
}

.tool-result {
  white-space: pre-wrap;
  word-break: break-word;
  font-family: 'SF Mono', 'Monaco', 'Inconsolata', 'Roboto Mono', 'Source Code Pro', monospace;
  background: rgba(59, 130, 246, 0.05);
  padding: 12px 16px;
  border-radius: 12px;
  border: 1px solid rgba(59, 130, 246, 0.1);
  font-size: 14px;
  line-height: 1.5;
  margin: 0;
  color: #1f2937;
}

.message.right .tool-result {
  background: rgba(255, 255, 255, 0.15);
  border-color: rgba(255, 255, 255, 0.2);
  color: rgba(255, 255, 255, 0.9);
}

.meta {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 12px;
  font-size: 12px;
  color: #9ca3af;
  padding-top: 8px;
  border-top: 1px solid rgba(59, 130, 246, 0.1);
}

.message.right .meta {
  color: rgba(255, 255, 255, 0.7);
  border-top-color: rgba(255, 255, 255, 0.2);
}

.time {
  font-weight: 500;
  letter-spacing: 0.3px;
}

.status {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-weight: 500;
  padding: 2px 8px;
  border-radius: 8px;
  font-size: 11px;
}

.status.sending {
  color: #3b82f6;
  background: rgba(59, 130, 246, 0.1);
}

.message.right .status.sending {
  color: rgba(255, 255, 255, 0.9);
  background: rgba(255, 255, 255, 0.2);
}

.status.failed {
  color: #ef4444;
  background: rgba(239, 68, 68, 0.1);
}

.message.right .status.failed {
  color: #fecaca;
  background: rgba(239, 68, 68, 0.2);
}

.meta-btn {
  border: none;
  background: rgba(59, 130, 246, 0.1);
  color: #3b82f6;
  cursor: pointer;
  padding: 4px 10px;
  border-radius: 8px;
  font-size: 11px;
  font-weight: 500;
  transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
  letter-spacing: 0.3px;
}

.meta-btn:hover {
  background: rgba(59, 130, 246, 0.15);
  transform: translateY(-1px);
}

.message.right .meta-btn {
  background: rgba(255, 255, 255, 0.2);
  color: white;
}

.message.right .meta-btn:hover {
  background: rgba(255, 255, 255, 0.3);
}

.meta-btn.retry {
  color: #f59e0b;
  background: rgba(245, 158, 11, 0.1);
}

.meta-btn.retry:hover {
  background: rgba(245, 158, 11, 0.15);
}

.message.right .meta-btn.retry {
  color: #fbbf24;
  background: rgba(251, 191, 36, 0.2);
}

.message.right .meta-btn.retry:hover {
  background: rgba(251, 191, 36, 0.3);
}

/* 响应式设计 */
@media (max-width: 768px) {
  .bubble {
    max-width: 85%;
    padding: 14px 16px;
    border-radius: 16px;
  }
  
  .text {
    font-size: 14px;
  }
  
  .tool-result {
    font-size: 13px;
    padding: 10px 12px;
  }
  
  .meta {
    gap: 8px;
    margin-top: 10px;
  }
  
  .meta-btn {
    padding: 3px 8px;
    font-size: 10px;
  }
}

@media (max-width: 480px) {
  .bubble {
    max-width: 90%;
    padding: 12px 14px;
  }
  
  .message {
    margin-bottom: 16px;
  }
  
  .bubble::before {
    display: none;
  }
}
</style>